/*单例模式练习9*/


#include <iostream>

/*饿汉模式*/
// 思想：在类内实例化对象，而不是类外
class Single1
{
private:
    Single1()
        :_a(10)
        ,_b(5.5)
    {}
    Single1(const Single1& s) = delete;
    ~Single1()  {}

    static Single1 _eton;

private:
    int _a;
    float _b;

public:
    void printData()
    {
        std::cout << _a << " " << _b << std::endl;
    }
    
    //不可以传值返回，因为拷贝了就不是单例了，而且拷贝构造delete了
    static Single1& getInstance()
    {
        return _eton;
    }

    // static Single1 _eton;
};

Single1 Single1::_eton;


// int main()
// {
//     Single1::getInstance().printData();
//     return 0;
// }


/*懒汉模式C98*/
#include <pthread.h>
class Single2
{
private:
    Single2()
        :_a(20)
        ,_b(7.3)
    {}
    Single2(const Single2& s) = delete;
    ~Single2()  {}
    
private:
    int _a;
    float _b;
    static pthread_mutex_t _mutex;  // POSIX 互斥锁
    static Single2* _eton;

public:
    void printData()
    {
        std::cout << _a << " " << _b << std::endl;
    }
    static Single2* getInstance()
    {
        if(_eton == nullptr)
        {
            pthread_mutex_lock(&_mutex);
            if(_eton == nullptr)
                _eton = new Single2;
            pthread_mutex_unlock(&_mutex);
            
        }
        return _eton;
    }

};

Single2* Single2:: _eton = nullptr;
pthread_mutex_t Single2::_mutex = PTHREAD_MUTEX_INITIALIZER;

// int main()
// {
//     Single2::getInstance()->printData();
//     return 0;
// }



/*懒汉模式C++11之后*/
class Single3
{
private:
    Single3()
        :_a(70)
        ,_b(6.6)
    {}
    Single3(const Single3& s) = delete;
    ~Single3()  {}
    
private:
    int _a;
    float _b;
 
public:
    void printData()
    {
        std::cout << _a << " " << _b << std::endl;
    }
    static Single3& getInstance()
    {
        //在C++11之后，支持静态局部变量是线程安全的
        //即：多个线程同时进来，_eton也只初始化一次
        static Single3 _eton;
        return _eton;
    }
};
int main()
{
    Single3::getInstance().printData();
    return 0;
}


